// Copyright (c) 2008-2010, Arne Claus
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the 
// following conditions are met:
//
// - Redistributions of source code must retain the above copyright notice, this list of conditions and the following 
//   disclaimer.
// - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following 
//   disclaimer in the documentation and/or other materials provided with the distribution.
// - Neither the name Arne Claus nor the names of any contributors may be used to endorse or promote products
//   derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 
// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#ifndef __INCLUDED_CBL_SERIALIZATION_H__
#define __INCLUDED_CBL_SERIALIZATION_H__

#include "CBL_Defines.h"
#include "CBL_AutoBuffer.h"
#include <string>
#include <vector>

CB_NAMESPACE_START

class ISerializer;

// -----------------------------------------------------------------------------------------------------------------
//	Baseclass for classes that have to be created dynamically by CClassFactory
//	Static class should only implement the Serializefunction.
// -----------------------------------------------------------------------------------------------------------------

#define SERIALIZE_FUNCTION() Serialize(CB_NS::ISerializer& _rSerializer)

class ISerializeable
{
public:
    virtual uint32 GetObjectVersion() { return 0; }
    virtual void SERIALIZE_FUNCTION() = 0;
};

// -----------------------------------------------------------------------------------------------------------------
//	Baseclass for a generic serializer. Overload at will.
// -----------------------------------------------------------------------------------------------------------------

class ISerializer
{
public:
    
    enum EOutputType
    {
        Writing = 0,
        Reading
    };

public:
    
    static const uint32 FlagCollectionItem  = 1 << 1;
    static const uint32 FlagRequiredField   = 1 << 2;
    static const uint32 FirstCustomFlag     = 1 << 3;
    
public:
    
    ISerializer(EOutputType _Type) : m_Type(_Type) {}
    virtual ~ISerializer() {}
    
    EOutputType GetOutputType() const	{ return m_Type; };
    bool IsWriting() const				{ return m_Type == Writing; }
    bool IsReading() const				{ return m_Type == Reading; }
    
    virtual Memory::CAutoBuffer<char> Flush() = 0;
    
    virtual bool Serialize(bool& _rValue, const char* _pName, uint32 _Flags=0) = 0;
    
    virtual bool Serialize(int8& _rValue, const char* _pName, uint32 _Flags=0) = 0;
    virtual bool Serialize(int16& _rValue, const char* _pName, uint32 _Flags=0) = 0;
    virtual bool Serialize(int32& _rValue, const char* _pName, uint32 _Flags=0) = 0;
    virtual bool Serialize(int64& _rValue, const char* _pName, uint32 _Flags=0) = 0;
    
    virtual bool Serialize(uint8& _rValue, const char* _pName, uint32 _Flags=0) = 0;
    virtual bool Serialize(uint16& _rValue, const char* _pName, uint32 _Flags=0) = 0;
    virtual bool Serialize(uint32& _rValue, const char* _pName, uint32 _Flags=0) = 0;
    virtual bool Serialize(uint64& _rValue, const char* _pName, uint32 _Flags=0) = 0;
    
    virtual bool Serialize(uint32& _rValue, const char** _pTranslationStringArray, uint32 _ArrayLength, const char* _pName, uint32 _Flags=0) = 0;
    
    virtual bool Serialize(float& _rValue, const char* _pNam, uint32 _Flags=0) = 0;
    virtual bool Serialize(double& _rValue, const char* _pName, uint32 _Flags=0) = 0;
    
    virtual bool Serialize(char* _pValue, size_t _BufferSize, const char* _pName, uint32 _Flags=0) = 0;
    virtual bool Serialize(wchar_t* _pValue, size_t _BufferSize, const char* _pName, uint32 _Flags=0) = 0;
    
    virtual bool Serialize(std::string& _rValue, const char* _pName, uint32 _Flags=0) = 0;
    virtual bool Serialize(std::wstring& _rValue, const char* _pName, uint32 _Flags=0) = 0;
    
    virtual bool Serialize(ISerializeable& _rObject, const char* _pName, uint32 _Flags=0) = 0;
    virtual bool Serialize(ISerializeable** _ppObject, const char* _pName, uint32 _Flags=0) = 0;
    
    virtual bool SerializeBlockStart(const char* _pName, uint32 _Flags=0) = 0;
    virtual bool SerializeBlockEnd(const char* _pName, uint32 _Flags=0) = 0;
    
public:
    
    template <typename TType>
    CB_FORCEINLINE void CB_INLINE_ATTR Serialize(std::vector<TType>& _rVector, const char* _pBlockName, const char* _pElementName, uint32 _Flags=0);
    
protected:
    
    EOutputType m_Type;
};

#include "CBL_Serialization.hpp"

CB_NAMESPACE_END

#endif